home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Graphics Programming (2nd Edition) / Visual Basic Graphics Programming 2nd Edition.iso / Src / Ch7 / Rotate.frm (.txt) < prev    next >
Encoding:
Visual Basic Form  |  1999-06-06  |  12.2 KB  |  345 lines

  1. VERSION 5.00
  2. Object = "{F9043C88-F6F2-101A-A3C9-08002B2F49FB}#1.2#0"; "COMDLG32.OCX"
  3. Begin VB.Form frmRotate 
  4.    Caption         =   "Rotate []"
  5.    ClientHeight    =   2895
  6.    ClientLeft      =   165
  7.    ClientTop       =   735
  8.    ClientWidth     =   3120
  9.    LinkTopic       =   "Form2"
  10.    ScaleHeight     =   2895
  11.    ScaleWidth      =   3120
  12.    StartUpPosition =   3  'Windows Default
  13.    Begin VB.PictureBox picResult 
  14.       Height          =   2295
  15.       Left            =   840
  16.       ScaleHeight     =   149
  17.       ScaleMode       =   3  'Pixel
  18.       ScaleWidth      =   157
  19.       TabIndex        =   4
  20.       Top             =   1440
  21.       Visible         =   0   'False
  22.       Width           =   2415
  23.    End
  24.    Begin VB.CommandButton cmdRotate 
  25.       Caption         =   "Rotate"
  26.       Height          =   375
  27.       Left            =   1200
  28.       TabIndex        =   3
  29.       Top             =   0
  30.       Width           =   855
  31.    End
  32.    Begin VB.TextBox txtAngle 
  33.       Height          =   285
  34.       Left            =   600
  35.       TabIndex        =   2
  36.       Text            =   "30"
  37.       Top             =   60
  38.       Width           =   495
  39.    End
  40.    Begin MSComDlg.CommonDialog dlgOpenFile 
  41.       Left            =   0
  42.       Top             =   360
  43.       _ExtentX        =   847
  44.       _ExtentY        =   847
  45.       _Version        =   393216
  46.    End
  47.    Begin VB.PictureBox picOriginal 
  48.       AutoSize        =   -1  'True
  49.       Height          =   2295
  50.       Left            =   120
  51.       ScaleHeight     =   149
  52.       ScaleMode       =   3  'Pixel
  53.       ScaleWidth      =   157
  54.       TabIndex        =   0
  55.       Top             =   480
  56.       Width           =   2415
  57.    End
  58.    Begin VB.Label Label1 
  59.       Caption         =   "Angle"
  60.       Height          =   255
  61.       Left            =   120
  62.       TabIndex        =   1
  63.       Top             =   60
  64.       Width           =   495
  65.    End
  66.    Begin VB.Menu mnuFile 
  67.       Caption         =   "&File"
  68.       Begin VB.Menu mnuFileOpen 
  69.          Caption         =   "&Open..."
  70.          Shortcut        =   ^O
  71.       End
  72.       Begin VB.Menu mnuFileSaveAs 
  73.          Caption         =   "Save &As..."
  74.          Shortcut        =   ^A
  75.       End
  76.    End
  77. Attribute VB_Name = "frmRotate"
  78. Attribute VB_GlobalNameSpace = False
  79. Attribute VB_Creatable = False
  80. Attribute VB_PredeclaredId = True
  81. Attribute VB_Exposed = False
  82. Option Explicit
  83. ' Rotate the image.
  84. Private Sub RotateImage(ByVal pic_from As PictureBox, ByVal pic_to As PictureBox, ByVal angle As Single)
  85. Dim white_pixel As RGBTriplet
  86. Dim input_pixels() As RGBTriplet
  87. Dim result_pixels() As RGBTriplet
  88. Dim bits_per_pixel As Integer
  89. Dim xmax_in As Integer
  90. Dim ymax_in As Integer
  91. Dim CxIn As Single
  92. Dim CyIn As Single
  93. Dim CxOut As Single
  94. Dim CyOut As Single
  95. Dim x_in As Single
  96. Dim y_in As Single
  97. Dim ix_in As Integer
  98. Dim iy_in As Integer
  99. Dim ix_out As Integer
  100. Dim iy_out As Integer
  101. Dim dx As Single
  102. Dim dy As Single
  103. Dim radius As Single
  104. Dim theta As Single
  105. Dim dx1 As Single
  106. Dim dx2 As Single
  107. Dim dy1 As Single
  108. Dim dy2 As Single
  109. Dim v11 As Integer
  110. Dim v12 As Integer
  111. Dim v21 As Integer
  112. Dim v22 As Integer
  113.     ' Set the white pixel's value.
  114.     With white_pixel
  115.         .rgbRed = 255
  116.         .rgbGreen = 255
  117.         .rgbBlue = 255
  118.     End With
  119.     ' Get the pixels from pic_from.
  120.     GetBitmapPixels pic_from, input_pixels, bits_per_pixel
  121.     ' Get the pixels from pic_to.
  122.     GetBitmapPixels pic_to, result_pixels, bits_per_pixel
  123.     ' Get the centers of both images.
  124.     CxIn = pic_from.ScaleWidth / 2
  125.     CyIn = pic_from.ScaleHeight / 2
  126.     CxOut = pic_to.ScaleWidth / 2
  127.     CyOut = pic_to.ScaleHeight / 2
  128.     ' Get the size of the original image.
  129.     xmax_in = pic_from.ScaleWidth - 1
  130.     ymax_in = pic_from.ScaleHeight - 1
  131.     ' Calculate the output pixel values.
  132.     For iy_out = 0 To pic_to.ScaleHeight - 1
  133.         For ix_out = 0 To pic_to.ScaleWidth - 1
  134.             ' Map the pixel value from
  135.             ' (ix_out, iy_out) to (x_in, y_in).
  136.             dx = ix_out - CxOut
  137.             dy = iy_out - CyOut
  138.             radius = Sqr(dx * dx + dy * dy)
  139.             theta = ATan2(dy, dx)
  140.             x_in = CxIn + radius * Cos(theta + angle)
  141.             y_in = CyIn + radius * Sin(theta + angle)
  142.             ' Find the nearest integral position.
  143.             ix_in = Int(x_in)
  144.             iy_in = Int(y_in)
  145.             ' See if this is in bounds.
  146.             If (ix_in >= 0) And (ix_in < xmax_in) And _
  147.                (iy_in >= 0) And (iy_in < ymax_in) _
  148.             Then
  149.                 ' The point lies within the image.
  150.                 ' Calculate its value.
  151.                 dx1 = x_in - ix_in
  152.                 dy1 = y_in - iy_in
  153.                 dx2 = 1# - dx1
  154.                 dy2 = 1# - dy1
  155.                 With result_pixels(ix_out, iy_out)
  156.                     ' Calculate the red value.
  157.                     v11 = input_pixels(ix_in, iy_in).rgbRed
  158.                     v12 = input_pixels(ix_in, iy_in + 1).rgbRed
  159.                     v21 = input_pixels(ix_in + 1, iy_in).rgbRed
  160.                     v22 = input_pixels(ix_in + 1, iy_in + 1).rgbRed
  161.                     .rgbRed = _
  162.                         v11 * dx2 * dy2 + v12 * dx2 * dy1 + _
  163.                         v21 * dx1 * dy2 + v22 * dx1 * dy1
  164.                     ' Calculate the green value.
  165.                     v11 = input_pixels(ix_in, iy_in).rgbGreen
  166.                     v12 = input_pixels(ix_in, iy_in + 1).rgbGreen
  167.                     v21 = input_pixels(ix_in + 1, iy_in).rgbGreen
  168.                     v22 = input_pixels(ix_in + 1, iy_in + 1).rgbGreen
  169.                     .rgbGreen = _
  170.                         v11 * dx2 * dy2 + v12 * dx2 * dy1 + _
  171.                         v21 * dx1 * dy2 + v22 * dx1 * dy1
  172.                     ' Calculate the blue value.
  173.                     v11 = input_pixels(ix_in, iy_in).rgbBlue
  174.                     v12 = input_pixels(ix_in, iy_in + 1).rgbBlue
  175.                     v21 = input_pixels(ix_in + 1, iy_in).rgbBlue
  176.                     v22 = input_pixels(ix_in + 1, iy_in + 1).rgbBlue
  177.                     .rgbBlue = _
  178.                         v11 * dx2 * dy2 + v12 * dx2 * dy1 + _
  179.                         v21 * dx1 * dy2 + v22 * dx1 * dy1
  180.                 End With
  181.             Else
  182.                 ' The point is outside the image.
  183.                 ' Use white.
  184.                 result_pixels(ix_out, iy_out) = white_pixel
  185.             End If
  186.         Next ix_out
  187.     Next iy_out
  188.     ' Set pic_to's pixels.
  189.     SetBitmapPixels pic_to, bits_per_pixel, result_pixels
  190.     pic_to.Picture = pic_to.Image
  191. End Sub
  192. ' Arrange the controls.
  193. Private Sub ArrangeControls(ByVal angle As Single)
  194. Dim new_wid As Single
  195. Dim new_hgt As Single
  196. Dim old_wid As Single
  197. Dim old_hgt As Single
  198.     ' Calculate the result's size.
  199.     old_wid = picOriginal.ScaleWidth
  200.     old_hgt = picOriginal.ScaleHeight
  201.     new_wid = Abs(old_wid * Cos(angle)) + Abs(old_hgt * Sin(angle))
  202.     new_hgt = Abs(old_wid * Sin(angle)) + Abs(old_hgt * Cos(angle))
  203.     new_wid = ScaleX(new_wid, vbPixels, ScaleMode) + picOriginal.Width - ScaleX(picOriginal.ScaleWidth, vbPixels, ScaleMode)
  204.     new_hgt = ScaleY(new_hgt, vbPixels, ScaleMode) + picOriginal.Height - ScaleY(picOriginal.ScaleHeight, vbPixels, ScaleMode)
  205.     ' Position the result PictureBox.
  206.     picResult.Move _
  207.         picOriginal.Left + picOriginal.Width + 120, _
  208.         picOriginal.Top, new_wid, new_hgt
  209.     picResult.Line (0, 0)-(picResult.ScaleWidth, picResult.ScaleHeight), _
  210.         picResult.BackColor, BF
  211.     picResult.Picture = picResult.Image
  212.     picResult.Visible = True
  213.     ' This makes the image resize itself to
  214.     ' fit the picture.
  215.     picResult.Picture = picResult.Image
  216.     ' Make the form big enough.
  217.     new_wid = picResult.Left + picResult.Width
  218.     If new_wid < cmdRotate.Left + cmdRotate.Width _
  219.         Then new_wid = cmdRotate.Left + cmdRotate.Width
  220.     new_hgt = picResult.Top + picResult.Height
  221.     Move Left, Top, new_wid + 237, new_hgt + 816
  222.     DoEvents
  223. End Sub
  224. ' Start in the current directory.
  225. Private Sub Form_Load()
  226.     picOriginal.AutoSize = True
  227.     picOriginal.ScaleMode = vbPixels
  228.     picOriginal.AutoRedraw = True
  229.     picResult.ScaleMode = vbPixels
  230.     picResult.AutoRedraw = True
  231.     dlgOpenFile.CancelError = True
  232.     dlgOpenFile.InitDir = App.Path
  233.     dlgOpenFile.Filter = _
  234.         "Bitmaps (*.bmp)|*.bmp|" & _
  235.         "GIFs (*.gif)|*.gif|" & _
  236.         "JPEGs (*.jpg)|*.jpg;*.jpeg|" & _
  237.         "Icons (*.ico)|*.ico|" & _
  238.         "Cursors (*.cur)|*.cur|" & _
  239.         "Run-Length Encoded (*.rle)|*.rle|" & _
  240.         "Metafiles (*.wmf)|*.wmf|" & _
  241.         "Enhanced Metafiles (*.emf)|*.emf|" & _
  242.         "Graphic Files|*.bmp;*.gif;*.jpg;*.jpeg;*.ico;*.cur;*.rle;*.wmf;*.emf|" & _
  243.         "All Files (*.*)|*.*"
  244.     Width = picOriginal.Left + picOriginal.Width + 120 + Width - ScaleWidth
  245.     Height = picOriginal.Top + picOriginal.Height + 120 + Height - ScaleHeight
  246. End Sub
  247. ' Rotate the picture.
  248. Private Sub cmdRotate_Click()
  249. Const PI = 3.14159265
  250. Dim angle As Single
  251.     ' Do nothing if no picture is loaded.
  252.     If picOriginal.Picture = 0 Then Exit Sub
  253.     ' Get the angle of rotation in radians.
  254.     On Error GoTo AngleError
  255.     angle = CSng(txtAngle.Text) * PI / 180
  256.     On Error GoTo 0
  257.     Screen.MousePointer = vbHourglass
  258.     picResult.Line (0, 0)-(picResult.ScaleWidth, picResult.ScaleHeight), _
  259.         picResult.BackColor, BF
  260.     DoEvents
  261.     ' Arrange picResult.
  262.     ArrangeControls angle
  263.     ' Rotate the image.
  264.     RotateImage picOriginal, picResult, angle
  265.     Screen.MousePointer = vbDefault
  266.     Exit Sub
  267. AngleError:
  268.     MsgBox "Invalid angle"
  269.     txtAngle.SetFocus
  270. End Sub
  271. ' Load the indicated file.
  272. Private Sub mnuFileOpen_Click()
  273. Dim file_name As String
  274.     ' Let the user select a file.
  275.     On Error Resume Next
  276.     dlgOpenFile.Flags = cdlOFNFileMustExist + cdlOFNHideReadOnly
  277.     dlgOpenFile.ShowOpen
  278.     If Err.Number = cdlCancel Then
  279.         Exit Sub
  280.     ElseIf Err.Number <> 0 Then
  281.         Beep
  282.         MsgBox "Error selecting file.", , vbExclamation
  283.         Exit Sub
  284.     End If
  285.     On Error GoTo 0
  286.     Screen.MousePointer = vbHourglass
  287.     DoEvents
  288.     file_name = Trim$(dlgOpenFile.FileName)
  289.     dlgOpenFile.InitDir = Left$(file_name, Len(file_name) _
  290.         - Len(dlgOpenFile.FileTitle) - 1)
  291.     Caption = "Rotate [" & dlgOpenFile.FileTitle & "]"
  292.     ' Open the original file.
  293.     On Error GoTo LoadError
  294.     picOriginal.Picture = LoadPicture(file_name)
  295.     On Error GoTo 0
  296.     ' Hide picResult.
  297.     picResult.Visible = False
  298.     If cmdRotate.Left + cmdRotate.Width > picOriginal.Left + picOriginal.Width Then
  299.         Width = cmdRotate.Left + cmdRotate.Width + 120 + Width - ScaleWidth
  300.     Else
  301.         Width = picOriginal.Left + picOriginal.Width + 120 + Width - ScaleWidth
  302.     End If
  303.     Height = picOriginal.Top + picOriginal.Height + 120 + Height - ScaleHeight
  304.     Screen.MousePointer = vbDefault
  305.     Exit Sub
  306. LoadError:
  307.     Screen.MousePointer = vbDefault
  308.     MsgBox "Error " & Format$(Err.Number) & _
  309.         " opening file '" & file_name & "'" & vbCrLf & _
  310.         Err.Description
  311. End Sub
  312. ' Save the transformed image.
  313. Private Sub mnuFileSaveAs_Click()
  314. Dim file_name As String
  315.     ' Let the user select a file.
  316.     On Error Resume Next
  317.     dlgOpenFile.Flags = cdlOFNOverwritePrompt + cdlOFNHideReadOnly
  318.     dlgOpenFile.ShowSave
  319.     If Err.Number = cdlCancel Then
  320.         Exit Sub
  321.     ElseIf Err.Number <> 0 Then
  322.         Beep
  323.         MsgBox "Error selecting file.", , vbExclamation
  324.         Exit Sub
  325.     End If
  326.     On Error GoTo 0
  327.     Screen.MousePointer = vbHourglass
  328.     DoEvents
  329.     file_name = Trim$(dlgOpenFile.FileName)
  330.     dlgOpenFile.InitDir = Left$(file_name, Len(file_name) _
  331.         - Len(dlgOpenFile.FileTitle) - 1)
  332.     Caption = "Rotate [" & dlgOpenFile.FileTitle & "]"
  333.     ' Save the transformed image into the file.
  334.     On Error GoTo SaveError
  335.     SavePicture picResult.Picture, file_name
  336.     On Error GoTo 0
  337.     Screen.MousePointer = vbDefault
  338.     Exit Sub
  339. SaveError:
  340.     Screen.MousePointer = vbDefault
  341.     MsgBox "Error " & Format$(Err.Number) & _
  342.         " saving file '" & file_name & "'" & vbCrLf & _
  343.         Err.Description
  344. End Sub
  345.